package wifiunion.com.notice.service;

import android.app.Notification;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
import java.net.Socket;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import wifiunion.com.notice.Constants;
import wifiunion.com.notice.R;
import wifiunion.com.notice.utils.SharedPreferencesUtils;


public class IntelligenceBackService extends Service {
    private static final String TAG = "wifiunion";
    private static final long HEART_BEAT_RATE = 35 * 1000;

    //重连
    private static final long RECONN_TIME = 60 * 1000;

    private ReadThread mReadThread;

    private SoftReference<Socket> mSocket;

    public Timer timer;

    private int recLen = 40;

    private long sendTime = 0L;
    /**
     * 线程池
     */
    ExecutorService cachedThreadPool;

    /**
     * 长连接ip,端口号
     * 场景登录手机号
     * 子场景的uuid
     */
    private String socketIp, socketPort, mPhone, mCommunityUuid;
    /**
     * 当前通知类型
     * 0 通知
     * 1 监控
     */
    private String type = "0";
    // For heart Beat
    private Handler mHandler;



    private Runnable heartBeatRunnable = new Runnable() {

        @Override
        public void run() {
            if (null != mHandler) {


//                if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
//                    type = TextUtils.isEmpty(type) ? "0" : type;

                    if (mSocket != null) {
//                        FileUtils.socketLog("时间：" + TimeUtil.getCurYMDTime()  + ",##定时发送心跳:" + type + "\n");
                        sendMsg(type);
                    } else {

//                        FileUtils.socketLog("时间：" + TimeUtil.getCurYMDTime()  + ",##定时发送心跳失败:Socket为空" + "\n");

                        //socket 为空 重现连接
                        //清空读线程
//                        if (null != mReadThread) {
//                            mReadThread.release();
//                            mReadThread = null;
//                        }
//                        //停止心跳包发送
//                        mHandler.removeCallbacksAndMessages(null);
//                        mHandler = null;
//
//                        //清空计时器
//                        if (timer != null) {
//                            timer.cancel();
//                            timer = null;
//                        }
//                        //重新初始化
//                        cachedThreadPool.execute(initSocketRunnable);

                    }
//                }
                mHandler.postDelayed(this, HEART_BEAT_RATE);
            }
        }
    };

    private Runnable reConRunnable = new Runnable() {
        @Override
        public void run() {
            if (null != timer) {
                timer.cancel();
                timer.purge();
                timer = null;
            }
            Log.e(TAG, "####reConRunnable");
//            FileUtils.socketLog("时间："+System.currentTimeMillis()+" 重连"+"\n");
            releaseLastSocket(mSocket);
            cachedThreadPool.execute(initSocketRunnable);
        }
    };


    @Override
    public void onCreate() {
        super.onCreate();

        mHandler = new Handler();
        IntentFilter intentFilter = new IntentFilter("close_socket");
        registerReceiver(cBroadcastReceiver, intentFilter);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        //创建通知栏
        Notification.Builder builder = new Notification.Builder(this);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        //显示通知栏，服务进程提权为前台服务。
        startForeground(10086, builder.build());//使用id：10086标记该通知栏

        if (mSocket == null || mSocket.get() == null) {
            if (TextUtils.isEmpty(socketIp) || TextUtils.isEmpty(socketPort)) {
                socketIp = intent.getStringExtra("socketip");
                socketPort = intent.getStringExtra("socketport");
                mPhone = intent.getStringExtra("phone");
                mCommunityUuid = intent.getStringExtra("partitionUuid");
//                type = intent.getStringExtra("type");
                cachedThreadPool = Executors.newCachedThreadPool();
                cachedThreadPool.execute(initSocketRunnable);

            } else {
                String newSocketIp = intent.getStringExtra("socketip");
                String newSocketPort = intent.getStringExtra("socketport");
                mPhone = intent.getStringExtra("phone");
                mCommunityUuid = intent.getStringExtra("partitionUuid");
//                type = intent.getStringExtra("type");
                if ((!TextUtils.isEmpty(newSocketIp) && !socketIp.equals(newSocketIp))) {
                    socketIp = newSocketIp;
                    socketPort = newSocketPort;
                }
                cachedThreadPool.execute(reConRunnable);
            }
        } else {
            String newSocketIp = intent.getStringExtra("socketip");
            String newSocketPort = intent.getStringExtra("socketport");
            mPhone = intent.getStringExtra("phone");
            mCommunityUuid = intent.getStringExtra("partitionUuid");
//            type = intent.getStringExtra("type");
            if ((!TextUtils.isEmpty(newSocketIp) && !socketIp.equals(newSocketIp))) {
                socketIp = newSocketIp;
                socketPort = newSocketPort;
            }
            cachedThreadPool.execute(reConRunnable);
        }


        return START_REDELIVER_INTENT;
    }

    BroadcastReceiver cBroadcastReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();
            if ("close_socket".equals(action)) {

//                FileUtils.socketLog("时间："+System.currentTimeMillis()+" close_socket指令"+"\n" );

                if (null != mReadThread) {
                    mReadThread.release();
                    mReadThread = null;
                }
                if (null != mSocket) {
                    Socket sk = mSocket.get();
                    if (null != sk) {
                        if (!sk.isClosed()) {
                            try {
                                sk.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            Log.i(TAG, "###releaseLast Socket close");
                        }
                    }
                    sk = null;
                    //新增清除
                    mSocket.clear();
                    mSocket = null;
                    Log.i(TAG, "###软引用清空");
                }
                releaseLastSocket(mSocket);
            }
        }
    };

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(cBroadcastReceiver);
        if (null != mSocket) {
            if (null != mHandler) {
                mHandler.removeCallbacksAndMessages(null);
            }
            if (null != timer) {
                timer.cancel();
                timer = null;
            }
            releaseLastSocket(mSocket);
            if (null != mReadThread) {
                mReadThread.release();
                mReadThread = null;
            }
        }
    }


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    public void sendMsg(final String msg) {
        Runnable downRunnable = null;
        Socket soc = mSocket.get();
        if (soc == null || null == mSocket.get()) {
//            downRunnable = reConRunnable;
        } else {
            downRunnable = new Runnable() {
                @Override
                public void run() {
                    Socket soc = mSocket.get();
                    OutputStream os = null;
                    try {
                        if (!soc.isClosed() && !soc.isOutputShutdown()) {
                            os = soc.getOutputStream();
                            String message = msg;
                            os.write(message.getBytes());
                            os.flush();
//                    sendTime = System.currentTimeMillis();//每次发送成数据，就改一下最后成功发送的时间，节省心跳间隔时间
                            Log.i(TAG, "###发送心跳成功   " + message);
//                            FileUtils.socketLog("时间：" + TimeUtil.getCurYMDTime() + ",##发送心跳成功:" + message + "\n");
                        }
                    } catch (Exception e) {
//                        FileUtils.socketLog("时间：" + TimeUtil.getCurYMDTime() + ",##发送心跳异常" + "\n");
//                        e.printStackTrace();
//                        StringBuffer sb = new StringBuffer();
//                        Writer writer = new StringWriter();
//                        PrintWriter printWriter = new PrintWriter(writer);
//                        e.printStackTrace(printWriter);
//                        Throwable cause = e.getCause();
//                        while (cause != null) {
//                            cause.printStackTrace(printWriter);
//                            cause = cause.getCause();
//                        }
//                        printWriter.close();
//                        String result = writer.toString();
//                        sb.append(result);
//                        FileUtils.socketLog(sb.toString());

                        //发送心跳失败
//                FileUtils.socketLog("时间：" + System.currentTimeMillis() + ",##发送心跳异常" + "\n");

//                        cachedThreadPool.execute(reConRunnable);
//                 }
                    }
                }

            };
            try {
                cachedThreadPool.execute(downRunnable);
            } catch (Exception e)
            {
                e.printStackTrace();
//                cachedThreadPool.execute(reConRunnable);
            }

        }
    }


    private void initSocket() {//初始化Socket
        try {
            recLen = 40;
            if(TextUtils.isEmpty(socketIp) || "null".equals(socketIp))
            {
                socketIp =  SharedPreferencesUtils.getParamSharedPreferences(this).socketIp;
            }

            if(TextUtils.isEmpty(socketPort) || "null".equals(socketPort))
            {
                socketPort =  SharedPreferencesUtils.getParamSharedPreferences(this).socketPort;
            }

            Socket so = new Socket(socketIp, Integer.parseInt(socketPort));

//            FileUtils.socketLog("时间："+System.currentTimeMillis()+",Socket初始化成功:"+socketIp +":"+socketPort+"\n" );

            mSocket = new SoftReference<Socket>(so);
            sendMobile();

            mReadThread = new ReadThread(so);
            mReadThread.start();

            if (mHandler == null) {
                mHandler = new Handler(getMainLooper());
            }
//            sendMsg(type);

            if (null != timer) {
                timer.cancel();
                timer.purge();
                timer = null;
            }
            timer = new Timer();
            timer.schedule(new RequestTimerTask(), 1000, 1000);// 接收超时的计时器
            mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//初始化成功后，就准备发送心跳包
        } catch (Exception e) {
            if (null != timer) {
                timer.cancel();
                timer.purge();
                timer = null;
            }
//            e.printStackTrace();
//
//            StringBuffer sb = new StringBuffer("");
//            sb.append("#####initSocket异常#####");
//            Writer writer = new StringWriter();
//            PrintWriter printWriter = new PrintWriter(writer);
//            e.printStackTrace(printWriter);
//            Throwable cause = e.getCause();
//            while (cause != null) {
//                cause.printStackTrace(printWriter);
//                cause = cause.getCause();
//            }
//            printWriter.close();
//            String result = writer.toString();
//            sb.append(result);
//            FileUtils.socketLog(sb.toString());


            if (mHandler == null) {
                Looper.prepare();
                if (null != mReadThread) {
                    mReadThread.release();
                    mReadThread = null;
                }
                mHandler = new Handler();
                mHandler.postDelayed(reConRunnable, RECONN_TIME);
                Looper.loop();
            } else {
                if (null != mReadThread) {
                    mReadThread.release();
                    mReadThread = null;
                }
                mHandler.postDelayed(reConRunnable, RECONN_TIME);
            }
        }
    }

    public void sendMobile() {
        if (null == mSocket || null == mSocket.get()) {
            return;
        }

        if(TextUtils.isEmpty(mPhone) || "null".equals(mPhone))
        {
            mPhone =  SharedPreferencesUtils.getParamSharedPreferences(this).phone;
        }

        if(TextUtils.isEmpty(mCommunityUuid) || "null".equals(mCommunityUuid))
        {
            mCommunityUuid =  SharedPreferencesUtils.getParamSharedPreferences(this).partitionUuid;
        }

        StringBuffer sb = new StringBuffer();
        sb.append(mPhone);
        sb.append("_");
        String str = UUID.randomUUID().toString().replace("-", "");
        sb.append(str);
        sb.append("_");
        sb.append(mCommunityUuid);

//        FileUtils.socketLog("时间："+TimeUtil.getCurYMDTime()+",注册码:"+sb.toString()+"\n" );

        Socket soc = mSocket.get();
        try {
            if (!soc.isClosed() && !soc.isOutputShutdown()) {
                OutputStream os = soc.getOutputStream();
                String message = sb.toString();
                os.write(message.getBytes());
                os.flush();
            } else {

            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    private void releaseLastSocket(SoftReference<Socket> mSocket) {
        try {
//            FileUtils.socketLog("releaseLastSocket时间："+System.currentTimeMillis()+(null != mSocket)+"\n" );

            if (null != mSocket) {
                Socket sk = mSocket.get();
                if (null != sk) {
                    if (!sk.isClosed()) {
                        sk.close();
                        Log.i(TAG, "###releaseLast Socket close");
                    }
                }
                sk = null;
                //新增清除
                mSocket.clear();
                Log.i(TAG, "###软引用清空");
            }
            if (null != mReadThread) {
                mReadThread.release();
                mReadThread = null;
            }
            if (timer != null) {
                timer.cancel();
                timer.purge();
                timer = null;
            }
            if (mHandler != null) {
                mHandler.removeCallbacksAndMessages(null);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     *
     */
    public Runnable initSocketRunnable = new Runnable() {
        @Override
        public void run() {
            initSocket();
        }
    };

    // Thread to read content from Socket
    class ReadThread extends Thread {
        private SoftReference<Socket> mSoftSocket;
        private boolean isStart = true;

        public ReadThread(Socket socket) {
            mSoftSocket = new SoftReference<Socket>(socket);
        }

        public void release() {
            isStart = false;
        }

        @Override
        public void run() {
            super.run();

            if (mSoftSocket != null) {
                Socket socket = mSoftSocket.get();
                if (null != socket) {
                    try {
                        InputStream is = socket.getInputStream();
                        byte[] buffer = new byte[1024 * 2];
                        int length = 0;
                        while (isStart && (null != socket) && !socket.isClosed() && !socket.isInputShutdown()
                                && (null != is) && ((length = is.read(buffer)) != -1)) {
                            if (length > 0) {
                                String message = new String(Arrays.copyOf(buffer,
                                        length)).trim();
                                Log.i(TAG, "#### 返回数据   " + message);
//                                FileUtils.socketLog("时间："+ TimeUtil.getCurYMDTime()  +",接收到数据:"+message+"\n" );
                                if (null != message) {
                                    recLen = 40;
                                    if ("h".equals(message)) {
                                        Log.i(TAG, "####心跳包   ");
                                    } else if ("reboot".equals(message)) {
                                        Intent intent = new Intent(Constants.RESTART_ACTION);
                                        sendBroadcast(intent);
                                    } else {
                                        try {
//                                            Intent intent = new Intent("com.wifiunion.intelligencegate.receiver");
//                                            Bundle bd = new Bundle();
//                                            bd.putString("pushEntity", message);
//                                            intent.putExtras(bd);
//                                            sendBroadcast(intent);
//                                            if ("3".equals(Constants.EXCEPTION_PAGE_VALUE)) {
//                                                sendAllRecordBroadCast(getApplicationContext(), message);
//                                            } else {
//
//                                            }
                                            sendNoticeBroadCast(getApplicationContext(), message);
                                        } catch (Exception e) {

                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();

//                        FileUtils.socketLog("时间："+System.currentTimeMillis()+" 读取文件错误"+"\n" );
//
//                        StringBuffer sb = new StringBuffer("");
//
////                        Writer writer = new StringWriter();
////                        PrintWriter printWriter = new PrintWriter(writer);
////                        e.printStackTrace(printWriter);
////                        Throwable cause = e.getCause();
////                        while (cause != null) {
////                            cause.printStackTrace(printWriter);
////                            cause = cause.getCause();
////                        }
////                        printWriter.close();
////                        String result = writer.toString();
////                        sb.append(result);
////
////                        FileUtils.socketLog(sb.toString());



                        if (mHandler != null) {
                            mHandler.removeCallbacksAndMessages(null);
                        }

                        //清空计时器
//                        if (timer != null) {
//                            timer.cancel();
//                            timer = null;
//                        }
                        // 如果不是异常情况，就重新初始化
//                        FileUtils.socketLog("时间："+System.currentTimeMillis()+" 读线程异常时 isStart的值"+isStart+"\n" );
//                        if (isStart) {
//                            FileUtils.socketLog("时间："+System.currentTimeMillis()+" 读线程异常从新初始化"+"\n" );
//                            cachedThreadPool.execute(initSocketRunnable);
//                        } else {
//                            if (null != mReadThread) {
//                                mReadThread.release();
//                                mReadThread = null;
//                            }
//                        }
                    }
                }
            } else {
                if (null != mReadThread) {
                    mReadThread.release();
                    mReadThread = null;
                }
                //停止心跳包发送
                mHandler.removeCallbacksAndMessages(null);
                //清空计时器
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                }
                //重新初始化
//                FileUtils.socketLog("时间："+System.currentTimeMillis()+" 软引用为空 重启"+"\n" );
                cachedThreadPool.execute(initSocketRunnable);
            }
        }
    }


    class RequestTimerTask extends TimerTask {
        public void run() {

            if (recLen < 0) {

//                FileUtils.socketLog("时间："+System.currentTimeMillis()+" 读线程超时 "+(null != mHandler)+"\n" );
                releaseLastSocket(mSocket);

                if (null != mHandler) {
                    Log.i(TAG, "###停止发送心跳包");
//                    FileUtils.socketLog("时间："+System.currentTimeMillis()+" 停止发送心跳包"+"\n" );
//                    mHandler.removeCallbacks(heartBeatRunnable);
//
//                    if (mHandler == null) {
//                        mHandler = new Handler(getMainLooper());
//                    }
//                    FileUtils.socketLog("时间："+System.currentTimeMillis()+" 延时2秒后再启动initSocketRunnable的任务"+"\n" );
                    initSocket();


                }
            }
            recLen--;
        }
    }


    /**
     * 更新下视频队列
     *
     * @param pe
     */
    private void sendNoticeBroadCast(Context context, String pe) {


//        PushEntity pushEntity = gson.fromJson(pe, PushEntity.class);
        Intent it = new Intent(Constants.PUSH_NOTICE_ACTION);
        Bundle bd = new Bundle();
        bd.putString("pushEntity", pe);
        it.putExtras(bd);

        context.sendBroadcast(it);
    }


    /**
     * 全部数据页面
     * 更新下视频队列
     *
     * @param pe
     */
//    private void sendAllRecordBroadCast(Context context, String pe) {
//
//        PushEntity pushEntity = gson.fromJson(pe, PushEntity.class);
//        Intent it = new Intent(Constants.PUSH_ALLRECORD_ACTION);
//        Bundle bd = new Bundle();
//        bd.putString("pushEntity", pe);
//        it.putExtras(bd);
//
//        if (TextUtils.isEmpty(Constants.ALLRECORD_SELECT_CAMERA_UNIQUE) || "0".equals(Constants.ALLRECORD_SELECT_CAMERA_UNIQUE) || Constants.ALLRECORD_SELECT_CAMERA_UNIQUE.contains(pushEntity.getDeviceUnique())) {
//            if (pushEntity.getType() == 1) {
//                if (pushEntity.getIsStranger() == 1 || pushEntity.getAlarmState() == 1) {
//                    ArrayList<PushEntity> p1 = mApplication.getAllWarnList();
//                    p1.add(0, pushEntity);
//                    if (p1.size() >= 4) {
//                        p1.remove(4);
//                    }
//                    mApplication.setAllWarnList(p1);
//                } else {
//                    ArrayList<PushEntity> p3 = mApplication.getAllList();
//                    p3.add(0, pushEntity);
//                    if (p3.size() >= 24) {
//                        p3.remove(24);
//                    }
//                    mApplication.setAllList(p3);
//                }
//            }
//            context.sendBroadcast(it);
//        }
//
//
//    }


}
